package it.stasbranger.myproject.client.managed.ui;

import com.google.gwt.core.client.GWT;

import com.google.gwt.editor.client.Editor;
import com.google.gwt.editor.client.EditorDelegate;
import com.google.gwt.editor.client.LeafValueEditor;
import com.google.gwt.editor.client.ValueAwareEditor;

import com.google.gwt.editor.client.adapters.EditorSource;
import com.google.gwt.editor.client.adapters.ListEditor;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;

import com.google.gwt.event.shared.EventBus;

import com.google.gwt.requestfactory.client.RequestFactoryEditorDriver;

import com.google.gwt.resources.client.CssResource;

import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;

import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ValueListBox;
import com.google.gwt.user.client.ui.Widget;

import it.stasbranger.myproject.client.managed.request.SuppliersHasRequestsProxy;

import it.stasbranger.myproject.client.scaffold.ui.CollectionRenderer;

import it.stasbranger.myproject.client.style.Styles;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class SuppliersHasRequestsListEditor extends Composite implements
		ValueAwareEditor<List<SuppliersHasRequestsProxy>>,
		LeafValueEditor<List<SuppliersHasRequestsProxy>> {

	interface Binder extends UiBinder<Widget, SuppliersHasRequestsListEditor> {

	}

	interface Driver extends
			RequestFactoryEditorDriver<List<SuppliersHasRequestsProxy>, //
			ListEditor<SuppliersHasRequestsProxy, NameLabel>> {

	}

	class NameLabel extends Composite implements
			ValueAwareEditor<SuppliersHasRequestsProxy> {
		final com.google.gwt.user.client.ui.NumberLabel<Integer> requestsIdrequestsEditor = new com.google.gwt.user.client.ui.NumberLabel<Integer>();
		final Image removeButton = new Image(Styles.resources().removeIcon());
		private SuppliersHasRequestsProxy suppliersHasRequests;

		public NameLabel() {
			this(null);
		}

		public NameLabel(final EventBus eventBus) {
			HorizontalPanel hp = new HorizontalPanel();
			removeButton.addClickHandler(new ClickHandler() {
				public void onClick(ClickEvent event) {
					removeSuppliersHasRequests(suppliersHasRequests);
				}
			});
			hp.add(removeButton);
			hp.add(requestsIdrequestsEditor);
			initWidget(hp);
		}

		public void flush() {
			// No-op
		}

		public void onPropertyChange(String... strings) {

		}

		public void setDelegate(EditorDelegate<SuppliersHasRequestsProxy> editorDelegate) {
		}

		public void setValue(SuppliersHasRequestsProxy proxy) {
			suppliersHasRequests = proxy;
		}
	}

	interface Style extends CssResource {

		String editorPanelHidden();

		String editorPanelVisible();

		String viewPanelHidden();

		String viewPanelVisible();
	}

	/**
	 * This is used by a ListEditor.
	 */
	private class NameLabelSource extends EditorSource<NameLabel> {

		@Override
		public NameLabel create(int index) {
			NameLabel label = new NameLabel();
			container.insert(label, index);
			return label;
		}

		@Override
		public void dispose(NameLabel requestsIdrequestsEditor) {
			requestsIdrequestsEditor.removeFromParent();
		}

		@Override
		public void setIndex(NameLabel editor, int index) {
			container.insert(editor, index);
		}
	}

	@UiField
	FlowPanel container;

	@UiField(provided = true)
	@Editor.Ignore
	ValueListBox<SuppliersHasRequestsProxy> picker = new ValueListBox<SuppliersHasRequestsProxy>(SuppliersHasRequestsProxyRenderer.instance(), new com.google.gwt.requestfactory.ui.client.EntityProxyKeyProvider<SuppliersHasRequestsProxy>());

	@UiField
	Button add;

	@UiField
	HTMLPanel editorPanel;

	@UiField
	Button clickToEdit;

	@UiField
	HTMLPanel viewPanel;

	@UiField
	Label viewLabel;

	@UiField
	Style style;

	boolean editing = false;

	private List<SuppliersHasRequestsProxy> values;

	private final List<SuppliersHasRequestsProxy> displayedList;

	public SuppliersHasRequestsListEditor() {

		// Create the UI
		initWidget(GWT.<Binder> create(Binder.class).createAndBindUi(this));

		// Create the driver which manages the data-bound widgets
		Driver driver = GWT.<Driver> create(Driver.class);

		// Use a ListEditor that uses our NameLabelSource
		ListEditor<SuppliersHasRequestsProxy, NameLabel> editor = ListEditor.of(new NameLabelSource());

		// Configure the driver
		ListEditor<SuppliersHasRequestsProxy, NameLabel> listEditor = editor;
		driver.initialize(listEditor);

		/*
		 * Notice the backing list is essentially anonymous.
		 */
		driver.display(new ArrayList<SuppliersHasRequestsProxy>());

		// Modifying this list triggers widget creation and destruction
		displayedList = listEditor.getList();

		editing = false;
	}

	@UiHandler("add")
	public void addClicked(ClickEvent e) {
		displayedList.add(picker.getValue());
		viewLabel.setText(makeFlatList(displayedList));
	}

	@UiHandler("clickToEdit")
	public void clickToEditClicked(ClickEvent e) {
		toggleEditorMode();
	}

	public void flush() {
	}

	public List<SuppliersHasRequestsProxy> getValue() {
		if (values == null && displayedList.size() == 0) {
			return null;
		}
		return new ArrayList<SuppliersHasRequestsProxy>(displayedList);
	}

	public void removeSuppliersHasRequests(SuppliersHasRequestsProxy suppliersHasRequests) {
		displayedList.remove(suppliersHasRequests);
	}

	public void onLoad() {
		makeEditable(false);
	}

	public void onPropertyChange(String... strings) {
	}

	public void setAcceptableValues(Collection<SuppliersHasRequestsProxy> proxies) {
		picker.setAcceptableValues(proxies);
	}

	public void setDelegate(EditorDelegate<List<SuppliersHasRequestsProxy>> editorDelegate) {
	}

	public void setValue(List<SuppliersHasRequestsProxy> values) {
		this.values = values;
		makeEditable(editing = false);
		if (displayedList != null) {
			displayedList.clear();
		}

		if (values != null) {
			for (SuppliersHasRequestsProxy e : values) {
				displayedList.add(e);
			}
		}
		viewLabel.setText(makeFlatList(values));
	}

	private void makeEditable(boolean editable) {
		if (editable) {
			editorPanel.setStylePrimaryName(style.editorPanelVisible());
			viewPanel.setStylePrimaryName(style.viewPanelHidden());
			clickToEdit.setText("Done");
		} else {
			editorPanel.setStylePrimaryName(style.editorPanelHidden());
			viewPanel.setStylePrimaryName(style.viewPanelVisible());
			clickToEdit.setText("Edit");
		}
	}

	private String makeFlatList(Collection<SuppliersHasRequestsProxy> values) {
		return CollectionRenderer.of(SuppliersHasRequestsProxyRenderer.instance()).render(values);
	}

	private void toggleEditorMode() {
		editing = !editing;
		makeEditable(editing);
	}
}
